#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@Project : gtmsAutoTestProject 
@File    : pos_order_pay_server.py
@IDE     : PyCharm 
@Author  : Mario
@Date    : 2022/5/10 15:45 
@Describe: POS订单支付接口业务实现
"""
from APIs.posApi.pay.pay_api import PayApi
from APIs.posApi.user.user_api import UserApi
from APIs.posApi.table.table_api import TableApi
from Comm.tools.toolsControl import ToolsHandler
from FastApi.enum.Interface_enum.error_enum import ERROR_ENUM
from FastApi.enum.pay_way_enum.order_pay_way_enum import ORDER_PAY_WAY_ENUM
from Comm.logUtils.logControl import LogHandler

logger = LogHandler().get_logger()


class PosOrderPayServer:
    """POS订单结台"""

    def __init__(self, brandCode, environment):
        """
        构造函数
        :param brandCode: 品牌编码
        :param environment: 环境
        """
        self.pay_api = PayApi(brandCode, environment)
        self.table_api = TableApi(brandCode, environment)
        self.user_api = UserApi(brandCode, environment)

    def user_work_status(self):
        """
        检查用户是否上班状态
        :return:
        """
        response = self.user_api.pos_login()
        work_status = ToolsHandler.get_json_result(response, '$..towork')
        # towork:是否上班中(0：未上班/已交班，1：上班中)
        if work_status == 0:
            logger.info("当前用户上班状态为:[{}],正在进行上班操作~".format(work_status))
            self.user_api.pos_work()

    def get_pay_mode_id(self, typename="现金支付"):
        """
        获取支付方式支付ID
        :param typename: 支付方式名称
        :return: 现金支付付款ID
        """
        pay_type_result = self.pay_api.pay_type_list()  # 调用支付方式接口获取接口返回信息
        pay_mode_id = None  # 支付方式ID
        if type(pay_type_result) is not dict:  # 判断支付方式接口请求是否成功
            pay_list = ToolsHandler.get_json_result(pay_type_result, '$.data.payTypeList')  # 支付方式的列表
            for x in range(len(pay_list)):  # 循环整个支付列表
                # 获取当前循环支付列表的支付方式名称
                pay_name = ToolsHandler.get_json_result(pay_type_result, '$.data.payTypeList[{}]'.format(x))
                if pay_name['typeName'] == typename:  # 判断支付方式的名称是否为typename
                    # 获取到typename的payModeId
                    pay_mode_id = ToolsHandler.get_json_result(pay_type_result, '$.data.payTypeList[{}].payModeList..payModeId'.format(x))
                    break
            if pay_mode_id is not None:  # 判断支付ID是否不为空
                logger.debug("获取到{}付款方式ID:{}".format(typename, pay_mode_id))
                return str(pay_mode_id)
            else:  # 接口请求失败原因大概率是因为中台门店付款方案单没有加人民币付款方式
                result_info = {"code": ERROR_ENUM.GET_PAYMENT_METHOD_ERROR.value[0],
                               "message": ERROR_ENUM.GET_PAYMENT_METHOD_ERROR.value[1]}
                logger.warning("获取{}付款方式失败!失败信息:{}".format(typename, result_info))
                return result_info
        elif type(pay_type_result) is dict:  # 如果获取支付方式方法返回类型等于字典类型,代表接口有问题
            logger.error("请求POS获取门店支付方式接口报错!错误原因:{}".format(pay_type_result))
            return pay_type_result

    def cancel_details_pay_mode(self, order_no, pay_detail):
        """
        取消当前订单的支付方式
        :param order_no: 订单号
        :param pay_detail: 支付订单详情
        :return: 待付金额
        """
        # 提取订单待支付金额
        order_pay_amount = ToolsHandler.get_json_result(pay_detail, '$.data.needPayAmount')
        # 提取订单的付款明细
        pay_mode_list = ToolsHandler.get_json_result(pay_detail, '$.data.payApiResponseList')
        if order_pay_amount == 0.0:  # 判断待付金额是否等于0,等于0直接返回
            # logger.debug("获取订单[{}]待支付金额成功,待付金额:[{}]".format(order_no, order_pay_amount))
            return order_pay_amount
        elif order_pay_amount > 0.0:  # 判断待付金额是否大于0,大于0需要判断支付明细中有没有新美大支付
            for i in range(len(pay_mode_list)):  # 循环付款明细列表
                # 取出支付code
                pay_code = ToolsHandler.get_json_result(pay_detail, '$.data.payApiResponseList[{}].payCode'.format(i))
                # 取出支付状态
                pay_status = ToolsHandler.get_json_result(pay_detail, '$.data.payApiResponseList[{}].status'.format(i))
                # 判断只有支付code等于支付类型枚举中新美大支付code一致并且支付状态等于0的才进行取消
                if pay_code == ORDER_PAY_WAY_ENUM.XIN_MEI_DA.value[0] and pay_status == 0:
                    # 取出支付订单号
                    pay_no = ToolsHandler.get_json_result(pay_detail, '$.data.payApiResponseList[{}].payNo'.format(i))
                    # 调用取消新美大支付接口进行取消
                    logger.info("已取消订单[{}]中一条未支付的新美大订单[{}]".format(order_no, pay_no))
                    self.pay_api.pay_xinMeiDa_cancel(order_no, pay_no)
            return order_pay_amount
        elif order_pay_amount < 0.0:  # 判断如果待付金额是否小于0元说明订单需要退平账目才能结账
            logger.info("当前订单[{}]待付金额[{}],即将执行退款操作~".format(order_no, str(order_pay_amount)))
            for i in range(len(pay_mode_list)):  # 循环付款明细列表
                # 取出支付订单号
                pay_no = ToolsHandler.get_json_result(pay_detail, '$.data.payApiResponseList[{}].payNo'.format(i))
                # 取出付款金额
                canRefundAmount = ToolsHandler.get_json_result(pay_detail, '$.data.payApiResponseList[{}].canRefundAmount'.format(i))
                order_pay_amount += canRefundAmount  # 付款金额相加
                # 调用退款接口
                logger.info("已退款[{}]元,支付订单号:[{}],业务订单号:[{}]".format(canRefundAmount, pay_no, order_no))
                self.pay_api.pay_common_refund(order_no, str(canRefundAmount), pay_no)
                # 调用【获取订单待支付金额】方法获取订单待支付金额
                order_pay_amount = self.order_pay_amount(order_no)
            return order_pay_amount

    def order_pay_amount(self, order_no):
        """
        获取订单待支付金额
        :param order_no: 订单号
        :return: 订单待付金额
        """
        pay_detail = self.pay_api.order_pay_detail(order_no)  # 调用订单详情接口获取订单详情
        if type(pay_detail) is not dict:  # 判断订单详情接口请求是否成功
            # 调用【取消当前订单的支付方式】方法取消订单的一些错误支付明细
            order_pay_amount = self.cancel_details_pay_mode(order_no, pay_detail)
            logger.debug("当前订单[{}]待付金额[{}]".format(order_no, order_pay_amount))
            return order_pay_amount
        elif type(pay_detail) is dict:  # 如果接口返回类型等于dict类型,代表接口有问题
            logger.error("请求POS订单详情接口报错!订单号[{}],错误原因:{}".format(order_no, pay_detail))
            return pay_detail

    def single_order_pay(self, order_no):
        """
        单个订单结账
        :param order_no: 订单号
        :return: 支付结果
        """
        self.user_work_status()  # 先检查用户是否上班
        # 调用支付订单详情接口,获取订单详情数据
        detail_whether_pay = self.pay_api.order_pay_detail(order_no)
        if type(detail_whether_pay) is not dict:  # 判断当前订单是否已经为待支付状态
            # 调用【获取订单待支付金额】方法获取订单的待支付金额
            order_pay_amount = self.order_pay_amount(order_no)
            if type(order_pay_amount) is not dict:  # 判断【获取订单待支付金额】方法返回是否成功
                if order_pay_amount > 0.0:  # 判断金额是否大于0
                    # 调用【获取支付方式支付ID】方法获取支付ID
                    pay_mode_id = self.get_pay_mode_id()
                    if type(pay_mode_id) is not dict:  # 判断调用【获取支付方式支付ID】方法是否成功
                        # 调用人民币支付接口进行结账
                        logger.info("正在使用人民币进行付款,付款金额:[{}],支付订单号:[{}]".format(str(order_pay_amount), order_no))
                        pay_result = self.pay_api.cash_pay(order_no, str(order_pay_amount), pay_mode_id)
                        if type(pay_result) is dict:  # 判断调用POS人民币付款接口是否失败。失败直接返回失败信息
                            logger.error("请求人民币付款接口报错!订单号[{}],错误原因:{}".format(order_no, pay_result))
                            return pay_result
                    # 如果【获取支付方式支付ID】方法返回为字典类型说明请求失败了,把错误原因进行返回
                    elif type(pay_mode_id) is dict:
                        return pay_mode_id
                # 如果人民币付款接口成功。就调用确认结台接口
                logger.debug("正在对订单[{}]进行结台操作~".format(order_no))
                end_table_result = self.pay_api.confirm_checkout(order_no)
                if type(end_table_result) is not dict:
                    result_info = {"code": 200, "message": "订单[{}]结账成功~".format(order_no)}
                    return result_info
                else:
                    logger.error("请求POS确认结台接口报错!订单号[{}],错误原因:{}".format(order_no, end_table_result))
                    return end_table_result
            # 如果【获取订单待支付金额】方法返回为字典类型说明请求失败了,把错误原因进行返回
            elif type(order_pay_amount) is dict:
                return order_pay_amount
        else:  # 如果不是待支付状态直接把POS接口信息进行返回
            logger.error("请求POS订单详情接口报错!订单号[{}],错误原因:{}".format(order_no, detail_whether_pay))
            return detail_whether_pay

    def multiple_order_pay(self):
        """按照品牌批量结账"""
        self.user_work_status()  # 先检查用户是否上班
        table_list = self.table_api.table_list('5')  # 调用POS台位列表接口获取台位订单信息
        if table_list is not dict:  # 判断请求是否成功
            # 获取台位下的所有订单号
            table_order = ToolsHandler.get_json_result(table_list, '$.data..orderNo')
            if type(table_order) is list:  # 判断当前品牌是否有订单
                pay_result = []  # 定义一个空列表用来存每个订单的结账结果信息
                for i in table_order:  # 循环订单列表
                    # 调用【单个订单结账】结账方法
                    order_pay_result = self.single_order_pay(str(i))
                    pay_result.append(order_pay_result)  # 把结账信息存入列表
                result_info = {"code": "200", "message": "请求成功", "data": pay_result}
                return result_info
            elif type(table_order) is str:
                # 调用【单个订单结账】结账方法
                order_pay_result = self.single_order_pay(table_order)
                result_info = {"code": "200", "message": "请求成功", "data": order_pay_result}
                return result_info
            else:
                result_info = {"code": "200", "message": "当前品牌没有可结账订单,请检查请求参数后重试~"}
                return result_info
        else:
            logger.error("请求POS台位列表接口报错!错误原因:{}".format(table_list))
            return table_list


if __name__ == '__main__':
    test = PosOrderPayServer('823884', 'uat')
    result = test.multiple_order_pay()
    print(result)
